﻿using CefSharp;
using CefSharp.WinForms;//仅v49（.net4.0)支持xp，依赖vcredist-2013(x86) 12.0.30501,
using FCRE.helper;
using FSLib.App.SimpleUpdater;
using FSLib.Network.Http;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Threading;
using System.Windows.Forms;

namespace FCRE
{
    public partial class FrmMain : Form
    {
        #region 本地考试系统

        private CmdHelper cmdHelper = new CmdHelper();
        private static string basedir = Application.StartupPath + @"\mysql5";
        private string mysqld = basedir + @"\bin\mysqld.exe";
        private string iniPath = basedir + @"\my.ini";
        private int mysqlport = 3309;
        private string datadir = basedir + @"\data";
        private string myjava = Application.StartupPath + @"\jre\bin\itjava.exe";
        private string centerurl = "";
        private string kcurl = "";
        private string docurl = Application.StartupPath + @"\web\lrw.html";
        private string errurl = Application.StartupPath + @"\web\404.html";
        private string waiturl = Application.StartupPath + @"\web\loading.html";
        private string closeurl = Application.StartupPath + @"\web\close.html";
        public string lip = "";
        private string appconf = Application.StartupPath + @"\application.properties";
        private int sysport = 8008;
        private string logpath = AppDomain.CurrentDomain.BaseDirectory + "logs" + @"\" + DateTime.Now.ToString("yyyy-MM-dd") + ".log";
        ChromiumWebBrowser webBrowser1;
        private delegate void IsLoginDelegate();
        private System.Threading.Timer timer;
        private int runid = 0;
        private bool dbok = false, sysok = false, scoresok = false, questok = false, stuok = false, centerok = false;
        private int kstype = 2;
        private string ksid = "";
        private int timecount = 0;
        private int nscores = 0, upscores = 0;

        #endregion

        public FrmMain()
        {
            if (Process.GetProcessesByName(Process.GetCurrentProcess().ProcessName).Length > 1)
            {
                MessageBox.Show("同一电脑只允许同时运行一个【信息技术考试服务器】！", this.Text,MessageBoxButtons.OK,MessageBoxIcon.Warning);
                Process.GetCurrentProcess().Kill();
                return;
            }
            this.SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.UserPaint | ControlStyles.DoubleBuffer, true);
            InitializeComponent();

            PubVar.uctepath = Application.StartupPath;
            CefSettings settings = new CefSettings();
            settings.Locale = "zh_CN";
            settings.AcceptLanguageList = "zh_CN";
            Cef.Initialize(settings);

            webBrowser1 = new ChromiumWebBrowser(docurl);
            webBrowser1.RegisterJsObject("jsObj", new JsEvent(this), false);// new CefSharp.BindingOptions() { CamelCaseJavascriptNames = false }); //交互数据 
            webBrowser1.DownloadHandler = new MyDownLoadFile();
            this.splitContainer1.Panel2.Controls.Add(webBrowser1);
            webBrowser1.Dock = DockStyle.Fill;
        }
        private void FrmMain_Load(object sender, EventArgs e)
        {
            this.Text = "娄底信息技术考试服务器" + this.ProductVersion;
            PubVar.dburl = PubVar.DecryptDES(PubVar.rurl);
            PubVar.dbport = "3066";//
            PubVar.webport = "48080";
            centerurl = "http://" + PubVar.dburl + ":" + PubVar.webport + "/kd124";//"http://192.168.31.193:8008/kd124";// 
            Updater.CheckUpdateSimple("http://" + PubVar.dburl + ":" + PubVar.webport + "/assets/upditserver/update/{0}", "update.xml");

            string[] ips = PubVar.GetLocalIpv4();
            if (ips == null || ips.Length == 0)
            {
                localips.Text = "";
                MessageBox.Show("请检查网络，确定本机是在局域网中");
                return;
            }
            else
            {
                int k = 0;
                foreach (string ip in ips)
                {
                    localips.Items.Add(ip);
                    if (k++ == 0) localips.Text = ip;
                }

                if (ips.Length > 1)
                {
                    MessageBox.Show("发现本机多网卡，请选择用于考试服务器的本机IP");
                }
            }
            ksaddr.Text = localips.Text;
            lip = localips.Text;
            //创建一个时间间隔为3s的定时器线程
            timer = new System.Threading.Timer(new System.Threading.TimerCallback(chgJeeRunUIStatus), null, 1000, 3000);
            wait("考试服务器正在启动，请稍候...");
            startMySQL();
            setSysport();
        }
        #region 改变UI组件的背景色或文本
        /// <summary>
        /// 改变控件的背景色
        /// </summary>
        public void ChangeBackColor(ToolStripStatusLabel control, Color color)
        {
            if (InvokeRequired)
            {
                Action<Color> action = x => { control.BackColor = color; };
                BeginInvoke(action, color);
            }
            else
            {
                control.BackColor = color;
            }
        }
        public void ChangeText(ToolStripStatusLabel control, string text)
        {
            if (InvokeRequired)
            {
                Action<string> action = x => { control.Text = text; };
                BeginInvoke(action, text);
            }
            else
            {
                control.Text = text;
            }
        }
        public void ChangeText(ToolStripTextBox control, string text)
        {
            if (InvokeRequired)
            {
                Action<string> action = x => { control.Text = text; };
                BeginInvoke(action, text);
            }
            else
            {
                control.Text = text;
            }
        }
        private delegate string delegateRead(ToolStripComboBox control);
        private string readControlText(ToolStripComboBox control)
        {
            return control.Text.Trim();
        }
        public string ReadText(ToolStripComboBox control)
        {
            if (InvokeRequired)
            {
                delegateRead reads = new delegateRead(readControlText);
                object text = BeginInvoke(reads, control);
                return (string)text;
            }
            else
            {
                return control.Text;
            }
        }
        #endregion
        /// <summary>
        /// 页面显示等待消息
        /// </summary>
        /// <param name="tips"></param>
        private void wait(string tips)
        {
            try
            {
                if(!webBrowser1.Address.Contains("loading")) webBrowser1.Load(waiturl);
                if (webBrowser1.IsBrowserInitialized)
                {
                    Thread.Sleep(500);//必须暂停才能生效
                    webBrowser1.ExecuteScriptAsync("document.getElementById('tipswait').innerHTML='" + tips + "';");
                }
            }
            catch (Exception ex)
            {
                LogHelper.WriteLog("script..." + ex.Message);
            }
        }
        /// <summary>
        /// 系统运行状态的变化
        /// </summary>
        private void chgJeeRunUIStatus(Object state)
        {
            if (timecount > 120) return;//每次状态改变，是在某个操作之后的2分钟之内检测
            timecount++;
            if (ProcessHelper.isPRunning("mysqld", mysqld))
            {
                if (runid == 1) { LoadingHelper.CloseForm(); runid = 0; webBrowser1.Load(docurl); }
                dbok = true;
                if (!MySqlHelper.getIsNotend("exam_exarrange", 1)
                    && !MySqlHelper.getIsNotend("sys_user", 1)
                    && !MySqlHelper.getIsNotend("sys_dept", 1)) stuok = true;
                else stuok = false;

                if (!MySqlHelper.getIsNotend("exam_question", 1)
                    && !MySqlHelper.getIsNotend("exam_paperdef", 1)
                    && !MySqlHelper.getIsNotend("exam_papertpl", 1)
                    && !MySqlHelper.getIsNotend("exam_qdb", 1)
                    && !MySqlHelper.getIsNotend("exam_qtype", 1)) questok = true;
                else questok = false;
            }
            else dbok = false;
            if (ProcessHelper.isPRunning("itjava", myjava) && PubVar.NetIsOK2("http://127.0.0.1:" + sysport + "/kc124"))
            {
                if (runid == 4)
                { LoadingHelper.CloseForm(); runid = 0; webBrowser1.Load(docurl); }
                sysok = true;
            }
            else sysok = false;
            //============change UI=============================================
            if (dbok)
            {
                ChangeBackColor(lbmysql, Color.Lime);
                ChangeText(lbmysql, "数据服务已开启");
                ThreadControl.ChangeEnable(btnSQL2, false);
                ThreadControl.ChangeEnable(btnCenter, true);
            }
            else
            {
                ChangeBackColor(lbmysql, Color.Red);
                ChangeText(lbmysql, "数据服务未开启");
                ThreadControl.ChangeEnable(btnSQL2, true);
                ThreadControl.ChangeEnable(btnCenter, false);
            }
            //====================================
            if (!stuok || !questok)
            {
                ChangeBackColor(lbstu, Color.Red);
                ChangeText(lbstu, "考试数据未就绪");
            }
            else
            {
                ChangeBackColor(lbstu, Color.Lime);
                ChangeText(lbstu, "考试数据已就绪");
            }
            //====================================
            if (stuok && questok && !sysok)
                ThreadControl.ChangeEnable(btnSys, true);
            else
                ThreadControl.ChangeEnable(btnSys, false);
            //====================================
            if (sysok)
            {
                ChangeBackColor(lbsys, Color.Lime);
                ChangeText(lbsys, "考试系统已运行");

                ThreadControl.ChangeEnable(btnCloseKs, true);
                kcurl = "http://" + lip + ":" + sysport + "/kc124";
                ThreadControl.ChangeEnable(btngokc, true);//有数据才能进考场
                ChangeText(ksaddr, lip);
                ThreadControl.ChangeEnable(panel1, true);
            }
            else
            {
                ChangeBackColor(lbsys, Color.Red);
                ChangeText(lbsys, "考试系统未运行");

                ThreadControl.ChangeEnable(btnCloseKs, false);
                ThreadControl.ChangeEnable(btngokc, false);
                ChangeText(ksaddr, "");
            }
            if (dbok && stuok && questok)
            {
                nscores = MySqlHelper.getN_sc();
                upscores = MySqlHelper.getUP_sc();
                ksid = MySqlHelper.getPaperid();
                if (nscores == 0)
                {
                    ChangeBackColor(lbscpaper, Color.Red);
                    ChangeText(lbscpaper, "暂无成绩数据");
                }
                else if (upscores == nscores)
                {
                    ChangeBackColor(lbscpaper, Color.Lime);
                    ChangeText(lbscpaper, "成绩数据已上传(" + nscores + ")");
                }
                else if (nscores > upscores)
                {
                    ChangeBackColor(lbscpaper, Color.Red);
                    ChangeText(lbscpaper, "成绩数据待上传(" + upscores.ToString() + "/" + nscores + ")");
                }
            }

        }

        /// <summary>
        /// 配置中的端口
        /// </summary>
        /// <param name="portPath"></param>
        /// <param name="key"></param>
        /// <returns></returns>
        private int readPort(string portPath, string key)
        {
            int port = 0;
            if (System.IO.File.Exists(portPath))
            {
                string[] allines = System.IO.File.ReadAllLines(portPath);
                for (int i = allines.Length - 1; i >= 0; i--)
                {
                    string a = allines[i];
                    string[] b = a.Split('=');
                    if (b[0].Equals(key))
                    {
                        port = Convert.ToInt16(b[1]);
                        break;
                    }
                }
            }
            return port;//0配置文件或端口不存在
        }
        /// <summary>
        /// 设置合适的MySQL端口
        /// </summary>
        private void setMySQLport()
        {
            try
            {
                int port = readPort(iniPath, "port");
                if (ProcessHelper.isPRunning("mysqld", mysqld))
                {
                    MySqlHelper.setlport(port);
                    return;
                }
                {
                    ZipHelper.UnpackArchive(basedir + @"\ini.zip", basedir, null, PubVar.DecryptDES(PubVar.zpwd));
                }
                for (port = 3309; port < 3319; port++)
                {
                    if (!PortHelper.portInUse(port)) break;
                }
                mysqlport = port;
                if (System.IO.File.Exists(iniPath))
                {
                    List<string> inis = new List<string>();
                    inis.Add("port=" + port);
                    MySqlHelper.setlport(port);
                    System.IO.File.AppendAllLines(iniPath, inis);
                }
            }
            catch (Exception ex) {LogHelper.WriteLog( ex.Message); }
        }
        /// <summary>
        /// 设置合适的考试系统端口
        /// </summary>
        private void setSysport()
        {
            try
            {
                int port = readPort(appconf, "server.port");
                if (ProcessHelper.isPRunning("itjava", myjava))
                {
                    sysport = port;
                    localport.Text = sysport.ToString();
                    return;
                }
                {
                    ZipHelper.UnpackArchive(Application.StartupPath + @"\appconf.zip", Application.StartupPath, null, PubVar.DecryptDES(PubVar.zpwd));
                }
                {
                    for (port = 8008; port > 8000; port--)
                    {
                        if (!PortHelper.portInUse(port)) break;
                    }
                }
                if (System.IO.File.Exists(appconf))
                {
                    List<string> inis = new List<string>();
                    inis.Add("server.port=" + port);
                    sysport = port;
                    localport.Text = sysport.ToString();
                    inis.Add("jdbc.url=jdbc:mysql://127.0.0.1:" + mysqlport + "/itfcre?useUnicode=true&allowPublicKeyRetrieval=true&characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai");
                    System.IO.File.AppendAllLines(appconf, inis);
                }
                wait("考试系统端口设置为：" + port);
            }
            catch (Exception ex) { LogHelper.WriteLog(ex.Message); }
        }

        /// <summary>
        /// 启动数据库
        /// </summary>
        private void startMySQL()
        {
            LoadingHelper.ShowLoadingScreen();
            runid = 1; timecount = 1;
            try
            {
                if (ProcessHelper.isPRunning("mysqld") && !ProcessHelper.isPRunning("mysqld", mysqld))
                {//非当前考试系统的数据库，先关
                    try
                    {
                        if (ProcessHelper.isPRunning("itjava", myjava))
                        {
                            ProcessHelper.killProc("itjava", "");//全杀
                        }
                        ProcessHelper.killProc("mysqld", "");
                    }
                    catch (Exception ex) { LogHelper.WriteLog("清理数据服务安装环境时遇到故障" + ex.Message); }
                }
                setMySQLport();
                string cmdstr = @" " + mysqld + "  --defaults-file=" + iniPath + "";
                if (!ProcessHelper.isPRunning("mysqld", mysqld))
                {
                    LogHelper.WriteLog("启动数据服务...");
                    ProcessStartInfo start = new ProcessStartInfo(@"mysql5\bin\mysqld.exe", @"--defaults-file=mysql5\my.ini");
                    start.CreateNoWindow = true;
                    start.WindowStyle = ProcessWindowStyle.Hidden;
                    Process.Start(start);
                }
            }
            catch (Exception ex) { LogHelper.WriteLog(ex.Message); wait("启动数据服务时遇到故障：" + ex.Message); }
        }
        /// <summary>
        /// 打开数据库
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnSQL2_Click(object sender, EventArgs e)
        {
            btnSQL2.Enabled = false;
            startMySQL();
        }

        /// <summary>
        /// 启动考试系统
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnSys_Click(object sender, EventArgs e)
        {
            try
            {
                if (!ProcessHelper.isPRunning("mysqld", mysqld))
                {
                    LoadingHelper.CloseForm();
                    wait("请先启动【数据服务】");
                    return;
                }

                if (ProcessHelper.isPRunning("itjava", myjava)) wait("系统正在运行...");
                else
                {
                    LoadingHelper.ShowLoadingScreen();
                    wait("正在启动考试系统...");
                    panel1.Enabled = false;
                    Thread.Sleep(50);
                    runid = 4; timecount = 1;
                    int port = localport.Text.ToInt32();
                    if (port != sysport)
                    {//手动更改port
                        ZipHelper.UnpackArchive(Application.StartupPath + @"\appconf.zip", Application.StartupPath, null, PubVar.DecryptDES(PubVar.zpwd));
                        if (System.IO.File.Exists(appconf))
                        {
                            List<string> inis = new List<string>();
                            inis.Add("server.port=" + port);
                            sysport = port;
                            inis.Add("jdbc.url=jdbc:mysql://127.0.0.1:" + mysqlport + "/itfcre?useUnicode=true&allowPublicKeyRetrieval=true&characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai");
                            System.IO.File.AppendAllLines(appconf, inis);
                        }
                    }
                    lip = localips.Text;
                    ksaddr.Text = lip;
                    string r = cmdHelper.cmdExcute(@"jre\bin\itjava.exe -jar fcre-2.0.jar", 15, 4);
                    LogHelper.WriteLog("启动考试系统时..." + r);
                }
            }
            catch (Exception ex) { LogHelper.WriteLog("启动考试系统时:" + ex.StackTrace);wait("启动考试系统时:" + ex.StackTrace); }
        }
        /// <summary>
        /// 进入考场
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btngokc_Click(object sender, EventArgs e)
        {
            LoadingHelper.ShowLoadingScreen();
            try
            {
                if (ProcessHelper.isPRunning("mysqld", mysqld) && ProcessHelper.isPRunning("itjava", myjava))
                {
                    timecount = 1;
                    webBrowser1.Load(kcurl);
                    btnDn.Enabled = false;
                    btnUp.Enabled = false;
                }
                else
                {
                    LoadingHelper.CloseForm();
                    //MessageBox.Show("检测到本地考试服务器未正常运行，不能考试，也不能监考", "系统提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                    wait("检测到【考试服务器】未正常运行，不能考试，也不能监考");
                    return;
                }
            }
            catch (Exception ex) { LogHelper.WriteLog("进入考场时:" + ex.StackTrace); wait("进入考场时:" + ex.StackTrace); }
            finally
            {
                LoadingHelper.CloseForm();
            }
        }
        /// <summary>
        /// 登录考场
        /// </summary>
        public void islogin2()
        {
            try
            {
                if (this.InvokeRequired)
                {
                    IsLoginDelegate d = new IsLoginDelegate(islogin2);
                    this.Invoke(d);
                }
                else
                {
                    if (PubVar.uid.Length > 0) kdcode.Text = PubVar.uid;//"考点：" + 
                }
            }
            catch (Exception e) { }
        }

        /// <summary>
        /// 关闭考试系统
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnCloseKs_Click(object sender, EventArgs e)
        {
            try
            {
                if (ProcessHelper.isPRunning("itjava", myjava))
                {
                    DialogResult result = MessageBox.Show("关闭【考试系统】会影响考试，您确定要关闭吗？", "系统警告", MessageBoxButtons.YesNo, MessageBoxIcon.Warning);
                    if (result == DialogResult.No) return;
                    else
                    {
                        LoadingHelper.ShowLoadingScreen();
                        //runid = 5;                       
                        timecount = 1;                        
                        for (int k = 0; k < 5; k++) {
                            if (ProcessHelper.isPRunning("itjava", myjava))
                                ProcessHelper.killProc("itjava", myjava, true);
                            else break;
                            Thread.Sleep(50);                            
                        }
                        LoadingHelper.CloseForm();
                        webBrowser1.Load(docurl);                      
                    }
                }
            }
            catch (Exception ex) { LogHelper.WriteLog("关闭本地系统时遇到故障" + ex.Message); wait("关闭【考试系统】时遇到故障" + ex.Message); }

        }

        /// <summary>
        /// 登录考试中心成功
        /// </summary>
        public void islogin()
        {
            try
            {
                if (this.InvokeRequired)
                {
                    IsLoginDelegate d = new IsLoginDelegate(islogin);
                    this.Invoke(d);
                }
                else
                {
                    if (ProcessHelper.isPRunning("mysqld", mysqld))
                    {
                        btnDn.Enabled = true;
                        btnUp.Enabled = true;
                    }
                }
            }
            catch (Exception e) { }
        }

        /// <summary>
        /// 连接考试中心
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnCenter_Click(object sender, EventArgs e)
        {
            try
            {
                timecount = 1;
                if (!ProcessHelper.isPRunning("mysqld", mysqld))
                {
                    //MessageBox.Show("请先启动数据服务");
                    wait("请先启动数据服务");
                    return;
                }
                if (PubVar.NetIsOK2(centerurl))
                {
                    webBrowser1.Load(centerurl);
                }
                else
                {
                    webBrowser1.Load(errurl);
                }
            }
            catch (Exception) { /*可选处理异常*/ }
        }


        /// <summary>
        /// 从中心检测是否开放下载、上传
        /// </summary>
        /// <param name="cmd"></param>
        /// <param name="postData"></param>
        /// <returns></returns>
        private string checkZX(string cmd, string postData)
        {
            string ans = "";
            try
            {
                String dfurl = centerurl + "/" + cmd;//
                var client = new HttpClient();
                client.Setting.Timeout = 60 * 1000;//超时1分钟.timeout设置的时间并不包括数据下载所耗费的时间。
                client.Setting.ReadWriteTimeout = 60 * 1000;

                int k = 1;
                while (k > 0)
                {
                    var context = client.Create<String>(HttpMethod.Post, dfurl, data: postData);
                    context.Send();
                    if (context.Response.Status.ToString() == "OK")
                    {
                        ans = context.ResponseContent.RawStringResult;
                        break;
                    }
                    else
                    {
                        context.Abort();
                        context.Dispose();
                        k++;
                        if (k > 3) { ans = context.ResponseContent.ToString(); break; }
                    }
                }
                return ans;
            }
            catch (Exception ex)
            {
                wait("连接【考试中心】的网络是否正常？【考试中心】的服务器是否正常开放？");
                return ex.Message;
            }
            finally
            {
                client.Clear();
            }
        }

        /// <summary>
        /// 从中心下载考试前相关数据
        /// </summary>
        /// <param name="data">传入对象</param>
        /// <returns>返回对象</returns>
        private void DnExam()
        {
            LoadingHelper.ShowLoadingScreen();
            try
            {
                if (!ProcessHelper.isPRunning("mysqld", mysqld))
                {
                    LoadingHelper.CloseForm();
                    //MessageBox.Show("数据服务没有启动，不允许下载考试数据");
                    wait("【数据服务】没有启动，不允许下载考试数据");
                    return;
                }
                if (ProcessHelper.isPRunning("itjava", myjava))
                {
                    LoadingHelper.CloseForm();
                    //MessageBox.Show("请先【关闭考试系统】");
                    wait("请先【关闭考试系统】");
                    return;
                }
                string isDnOK = checkZX("hasPaperdef", "");//
                if (isDnOK.Equals("false")) //
                {
                    LoadingHelper.CloseForm();
                    //MessageBox.Show("网络质量不佳，请尝试重新点击下载或者考试中心没有开放考试任务。", "系统提醒", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                    wait("网络质量不佳，请尝试重新点击下载或者【考试中心】没有开放考试任务");
                    return;
                }
                LoadingHelper.CloseForm();
                if (MessageBox.Show("你确定要下载中心的数据吗？", "系统提示", MessageBoxButtons.OKCancel, MessageBoxIcon.Question) == DialogResult.OK)
                {
                    if (MessageBox.Show("【确定】清空本地考试系统中的所有数据，【取消】跳过已下载数据？", "系统提醒", MessageBoxButtons.OKCancel, MessageBoxIcon.Warning) == DialogResult.OK)
                    {
                        if (!lockinput())
                        {
                            //MessageBox.Show("密码错误，不能进行下一步操作！！！", "系统提醒", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                            wait("密码错误，不能进行下一步操作！！！");
                            return;
                        }
                        //LoadingHelper.ShowLoadingScreen();
                        timecount = 1;
                        wait("清除本地数据...");
                        LogHelper.WriteLog(PubVar.uid + "清除本地数据...");
                        int a = MySqlHelper.cleanAllData();

                        if (a != 0)
                        {
                            LoadingHelper.CloseForm();
                            MessageBox.Show("清除数据时遇到故障！！！请查看日志文件");
                            cmdHelper.cmdExcute("START NOTEPAD \"" + logpath + "\"", 5);
                            return;
                        }
                        LogHelper.WriteLog(PubVar.uid + "下载中心数据...");
                        //==================正在下载中心数据（自带清除）...=================================================
                        if (backgroundWorker2.IsBusy) backgroundWorker2.CancelAsync(); //提交取消命令,但还未取消
                        backgroundWorker2.RunWorkerAsync();
                    }
                    else//取消全部清除，跳过已下载
                    {
                        //LoadingHelper.ShowLoadingScreen();
                        timecount = 1;
                        LogHelper.WriteLog(PubVar.uid + "下载中心数据...");
                        //==================正在下载中心数据（自带清除）...=================================================
                        if (backgroundWorker2.IsBusy) backgroundWorker2.CancelAsync(); //提交取消命令,但还未取消
                        backgroundWorker2.RunWorkerAsync();
                    }
                }
            }
            catch (Exception ex)
            {
                LogHelper.WriteLog("下载数据时" + ex.Message);
                //MessageBox.Show("下载失败！" + ex.Message);
                wait("下载数据时" + ex.Message);
            }

        }
        /// <summary>
        /// 下载数据
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnDn_Click(object sender, EventArgs e)
        {
            DnExam();
        }
        private void backgroundWorker2_DoWork(object sender, DoWorkEventArgs e)
        {
            //LoadingHelper.ShowLoadingScreen();
            ThreadControl.ChangeEnable(panel1, false);
            ChangeText(lbstu, "考试数据下载中...");
            ChangeBackColor(lbstu, Color.Gold);
            backgroundWorker2.ReportProgress(0, "Working...");
            //string ksid0 = MySqlHelper.getPaperid();
            String dfurl = centerurl + "/dnData";
            MySqlHelper.getDblink(PubVar.dblink);
            int m = MySqlHelper.tnames.Length - 1;//1;//
            for (int k = 1; k <= m; k++)
            {
                if (backgroundWorker2.CancellationPending)
                {
                    e.Cancel = true;
                    return;
                }

                string tname = MySqlHelper.tnames[k - 1];
                string tnamecn = MySqlHelper.tnamescn[k - 1];

                var client = new HttpClient();
                client.Setting.Timeout = 60 * 1000;//超时1分钟.timeout设置的时间并不包括数据下载所耗费的时间。
                client.Setting.ReadWriteTimeout = 60 * 1000;
                try
                {
                    {
                        string ksid = Convert.ToString(MySqlHelper.ExecuteScalar(MySqlHelper.LConn, CommandType.Text, "select id from exam_paperdef where status=1"));
                        int qdbid = Convert.ToUInt16(MySqlHelper.ExecuteScalar(MySqlHelper.LConn, CommandType.Text, "select qdbid from exam_papertpl where ksid='" + ksid + "'"));
                        var context = client.Create<JsonContent>(HttpMethod.Post, dfurl, data: "id=" + MySqlHelper.mydeptid + "&tname=" + tname + "&ksid=" + ksid + "&qdbid=" + qdbid);
                        context.Send();
                        if (context.Response.Status.ToString() == "OK")
                        {
                            string result = context.ResponseContent.RawStringResult;
                            JsonContent jo = JsonConvert.DeserializeObject<JsonContent>(result);
                            if (jo.ids.Equals("0"))
                            {
                                LogHelper.WriteLog("未发现" + tnamecn + "数据");
                                wait("未发现【" + tnamecn + "】数据");
                                if(k==m) MySqlHelper.setIsend(tname, 1);//只有考生数据不一定有下载
                                continue;//没有相应数据
                            }
                            else if (jo.ids.StartsWith("err"))
                            {
                                wait("下载报错..." + jo.ids);
                                LogHelper.WriteLog("下载报错..." + jo.ids);
                            }
                            else if (jo.ids.StartsWith("INSERT INTO "))
                            {
                                /*MySqlHelper.updateData(MySqlHelper.LConn, ds);
                                ds = JsonConvert.DeserializeObject<DataSet>(jo.ids);
                                MySqlHelper.insertData(MySqlHelper.LConn, ds,tname);*/
                                //int m = MySqlHelper.ExecuteTrans(MySqlHelper.LConn, CommandType.Text, jo.ids);
                                if (MySqlHelper.getIsNotend(tname, 1))
                                {
                                    int n = MySqlHelper.ExecuteTrans(MySqlHelper.LConn, CommandType.Text, jo.ids);
                                    if (n <= 0)
                                    {
                                        wait("下载后添加报错..." + tnamecn);
                                        LogHelper.WriteLog("下载后添加报错..." + tnamecn);
                                    }
                                    else
                                    {
                                        MySqlHelper.setIsend(tname, 1);
                                        wait("已下载【" + tnamecn + "】数据");
                                    }
                                    if (tname.Equals("sys_user"))
                                        MySqlHelper.ExecuteNonQuery(MySqlHelper.LConn, CommandType.Text, "update sys_user_role set user_id='" + MySqlHelper.mydeptid + "'");
                                }

                            }

                        }
                    }
                }
                catch (Exception ex)
                {
                    LogHelper.WriteLog("dnR:" + ex.Message + "\r\n可能网络不稳定，请尝试重新运行考试服务器再下载");
                    MessageBox.Show("可能网络不稳定，下载数据时遇到故障！！！请查看日志文件");
                    cmdHelper.cmdExcute("START NOTEPAD \"" + logpath + "\"", 5);
                    if (backgroundWorker2.IsBusy) backgroundWorker2.CancelAsync();
                    continue;
                }
                finally
                {
                    client.Clear();
                }

                backgroundWorker2.ReportProgress((int)((double)(k * 100) / m), "Working...");
                using (Graphics gr = scoreBar.ProgressBar.CreateGraphics())
                {
                    gr.SmoothingMode = SmoothingMode.AntiAlias;
                    string text = k.ToString() + "/" + m.ToString();
                    gr.DrawString(text, SystemFonts.DefaultFont, Brushes.Blue,
                        new PointF(scoreBar.Width / 2 - (gr.MeasureString(text, SystemFonts.DefaultFont).Width / 2.0F),
                        scoreBar.Height / 2 - (gr.MeasureString(text, SystemFonts.DefaultFont).Height / 2.0F)));
                }
            }
            backgroundWorker2.ReportProgress(100, "Complete!"); LoadingHelper.CloseForm();
        }

        private void backgroundWorker2_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            scoreBar.Value = e.ProgressPercentage;
        }

        private void backgroundWorker2_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            if (e.Error != null)
            {
                wait("下载考试数据时错误：\r\n" + e.Error.Message);
                //MessageBox.Show("下载考试数据时错误：\r\n" + e.Error.Message);
            }
            else if (e.Cancelled)
            {//判断是否用户手动取消
            }
            else
            {//判断是否正常结束
                webBrowser1.Load(docurl);
                MessageBox.Show("完成下载考试数据！！！", "系统提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
                timecount = 1;
                //LoadingHelper.CloseForm();
                ThreadControl.ChangeEnable(panel1, true);
                ChangeText(lbstu, "考试数据下载完成");
                ChangeBackColor(lbstu, Color.Lime);
                
            }
        }



        /// <summary>
        /// 向中心上传成绩数据
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        private void UpExam()
        {
            LoadingHelper.ShowLoadingScreen();
            try
            {
                if (!ProcessHelper.isPRunning("mysqld", mysqld))
                {
                    LoadingHelper.CloseForm();
                    //MessageBox.Show("数据服务没有启动，无法上传成绩数据", "系统提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                    wait("【数据服务】没有启动，无法上传成绩数据");
                    return;
                }
                if (MySqlHelper.getNoUP_sc() == 0)
                {
                    LoadingHelper.CloseForm();
                    //MessageBox.Show("没有需要上传的成绩数据", "系统提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                    wait("没有需要上传的成绩数据");
                    return;
                }
                if (ProcessHelper.isPRunning("itjava", myjava))
                {
                    LoadingHelper.CloseForm();
                    //MessageBox.Show("请先【关闭考试系统】");
                    wait("请先【关闭考试系统】");
                    return;
                }
                //应该检测考试号ksid.避免进入错误的考试也能上传。
                ksid = MySqlHelper.getPaperid();
                string isDnOK = checkZX("canUp", "ksid=" + ksid);
                if (isDnOK.Equals("false"))
                {
                    LoadingHelper.CloseForm();
                    //MessageBox.Show("考试中心没有开放考试编号为【"+ksid+"】的上传权限或者网络质量不佳，请尝试重新点击上传", "系统提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                    wait("考试中心没有开放考试编号为【" + ksid + "】的上传权限或者网络质量不佳，请尝试重新点击上传");
                    return;
                }
                LoadingHelper.CloseForm();
                {
                    if (MessageBox.Show("你确定要上传数据到中心吗？", "系统提示", MessageBoxButtons.OKCancel, MessageBoxIcon.Question) == DialogResult.OK)
                    {
                        //LoadingHelper.ShowLoadingScreen();
                        timecount = 1;
                        wait("清洗成绩数据...");
                        LogHelper.WriteLog(PubVar.uid + "清洗成绩数据...");
                        MySqlHelper.clearScores();
                        nscores = MySqlHelper.getN_sc();
                        //MessageBox.Show("待上传成绩数：" + MySqlHelper.getNoUP_sc(), "系统提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
                        wait("待上传成绩数..." + MySqlHelper.getNoUP_sc());
                        LogHelper.WriteLog(PubVar.uid + "分批上传成绩数据..." + nscores);
                        //LoadingHelper.CloseForm();
                        backgroundWorker1.RunWorkerAsync();//进入
                    }
                }
            }
            catch (Exception ex) { LogHelper.WriteLog("上传数据时遇到错误：" + ex.Message);wait("上传数据时遇到错误：" + ex.Message); }
        }

        /// <summary>
        /// 上传数据
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnUp_Click(object sender, EventArgs e)
        {
            UpExam();
        }


        /// <summary>
        /// BackgroundWorker类允许您在单独的线程上执行某个可能导致用户界面（UI）停止响应的耗时操作（比如文件下载数据库事务等），并且想要一个响应式的UI来反应当前耗时操作的进度。 
        ///BackgroundWorker组件提供了一种执行异步操作（后台线程）的同时，并且还能显示操作进度的解决方案。
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            //LoadingHelper.ShowLoadingScreen();
            ThreadControl.ChangeEnable(panel1, false);
            ChangeText(lbscpaper,"成绩数据上传中...");
            ChangeBackColor(lbscpaper, Color.Gold);
            backgroundWorker1.ReportProgress(0, "Working...");
            string ksid0 = MySqlHelper.getPaperid();
            String dfurl = centerurl + "/upData";
            while (MySqlHelper.getNoUP_sc() > 0)
            {
                DataSet ds = MySqlHelper.GetDataSet(MySqlHelper.LConn, CommandType.Text, "select ksid, uid,score,score1,score2,score3,paperdata,jjtime,dept_id,dept_name,classg,user_name,isup from exam_scores where ksid=\"" + ksid0 + "\" and isup=0 limit 10");
                string json = JsonConvert.SerializeObject(ds, Formatting.None);
                json = json.Substring(9);
                int len = json.Length;
                json = json.Substring(0, len - 1);
                json = json.Replace("dept_id", "deptId").Replace("dept_name", "deptName").Replace("user_name", "userName");

                var client = new HttpClient();
                client.Setting.Timeout = 60 * 1000;//超时1分钟.timeout设置的时间并不包括数据下载所耗费的时间。
                client.Setting.ReadWriteTimeout = 60 * 1000;
                try
                {
                    {
                        var context = client.Create<JsonContent>(HttpMethod.Post, dfurl, data: "ksid=" + ksid0 + "&ds=" + json);
                        context.Send();
                        if (context.Response.Status.ToString() == "OK")
                        {
                            JsonContent jo = JsonConvert.DeserializeObject<JsonContent>(context.ResponseContent.RawStringResult);
                            if (jo.ids.Equals("1"))
                                MySqlHelper.updateData(MySqlHelper.LConn, ds);
                            else
                                LogHelper.WriteLog("upd..." + jo.ids);
                        }
                        
                    }
                }
                catch (Exception ex)
                {
                    LogHelper.WriteLog("updR:" + ex.Message + "\r\n可能网络不稳定，请尝试重新运行考试服务器再上传");
                    MessageBox.Show("可能网络不稳定，上传数据时遇到故障！！！请查看日志文件");
                    cmdHelper.cmdExcute("START NOTEPAD \"" + logpath + "\"", 5);
                    break;
                }
                finally
                {
                    ds.Clear();
                    client.Clear();
                }
                int updn = MySqlHelper.getUP_sc();
                wait("已完成上传的成绩数：" + updn);
                backgroundWorker1.ReportProgress((int)((double)(updn * 100) / nscores), "Working...");
                using (Graphics gr = scoreBar.ProgressBar.CreateGraphics())
                {
                    //Switch to Antialiased drawing for better (smoother) graphic results
                    gr.SmoothingMode = SmoothingMode.AntiAlias;
                    string text = updn.ToString() + "/" + nscores.ToString();
                    gr.DrawString(text, SystemFonts.DefaultFont, Brushes.Blue,
                        new PointF(scoreBar.Width / 2 - (gr.MeasureString(text, SystemFonts.DefaultFont).Width / 2.0F),
                        scoreBar.Height / 2 - (gr.MeasureString(text, SystemFonts.DefaultFont).Height / 2.0F)));
                }
            }
            backgroundWorker1.ReportProgress(100, "Complete!");

        }

        private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            scoreBar.Value = e.ProgressPercentage;
        }

        private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            BackgroundWorker worker = sender as BackgroundWorker;
            //判断是否由错误造成意外中止
            if (e.Error != null)
            {
                wait("上传成绩数据时错误：\r\n" + e.Error.Message);
                //MessageBox.Show("上传成绩数据时错误：\r\n" + e.Error.Message);
            }
            else if (e.Cancelled)
            {//判断是否用户手动取消
            }
            else
            {//判断是否正常结束
                webBrowser1.Load(docurl);
                MessageBox.Show("共计完成上传" + nscores + "份成绩数据！！！", "系统提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
                //LoadingHelper.CloseForm();
                ThreadControl.ChangeEnable(panel1, true);
                ChangeText(lbscpaper, "成绩数据已上传("+ nscores + ")");
                ChangeBackColor(lbscpaper, Color.Lime);
                
            }
        }

        private void btnMysql_MouseHover(object sender, EventArgs e)
        {
            Cursor = Cursors.Hand;
        }

        private void btnMysql_MouseLeave(object sender, EventArgs e)
        {
            Cursor = Cursors.Default;
        }

        /// <summary>
        /// 关闭窗口前的事件处理
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void FrmMain_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (timer != null) timer.Dispose();
            LoadingHelper.ShowLoadingScreen();
            wait("正在关闭考试服务器，请稍候...");
            panel1.Enabled = false;
            statusStrip1.Enabled = false;
            toolStrip1.Enabled = false;
            Cef.Shutdown();//
        }
        private bool lockinput()
        {
            FrmPwd wn = new FrmPwd();
            wn.StartPosition = FormStartPosition.CenterParent;
            if (DialogResult.OK == wn.ShowDialog())
            {
                if (PubVar.pwd.Equals(PubVar.pwd2))
                {
                    LogHelper.WriteLog("已输入正确密码确认清除所有数据");
                    return true;
                }
            }
            return false;
        }
    }
    public class JsEvent
    {
        FrmMain mform;
        public JsEvent(FrmMain a)
        {
            mform = a;
        }
        public void isLogin(string data)
        {
            try
            {
                string[] d = data.Split('|');
                PubVar.dblink = d[0];
                PubVar.uid = d[1];
                PubVar.pwd = d[2];

                mform.islogin();
            }
            catch (Exception e)
            {
                LogHelper.WriteLog("js" + e.Message);
            }
        }
        public void isLogin2(string data)
        {
            try
            {
                string[] d = data.Split('|');
                PubVar.uid = d[1];
                mform.islogin2();
            }
            catch (Exception e)
            {
                LogHelper.WriteLog("js" + e.Message);
            }
        }
    }
}
